/*
 * Copyright (c) 2003-2009 jMonkeyEngine
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 * * Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright
 *   notice, this list of conditions and the following disclaimer in the
 *   documentation and/or other materials provided with the distribution.
 *
 * * Neither the name of 'jMonkeyEngine' nor the names of its contributors 
 *   may be used to endorse or promote products derived from this software 
 *   without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package edu.ieslaferreria.creditsintesis.builders;

import com.jme.scene.state.LightState;
import com.jmex.terrain.TerrainPage;
import edu.ieslaferreria.creditsintesis.logicgame.actions.ConfigurationMapEvent;
import java.net.URL;


import com.jme.bounding.BoundingBox;
import com.jme.image.Texture;
import com.jme.light.DirectionalLight;
import com.jme.math.Vector3f;
import com.jme.renderer.ColorRGBA;
import com.jme.scene.Node;
import com.jme.scene.state.CullState;
import com.jme.scene.state.TextureState;
import com.jme.system.DisplaySystem;
import com.jme.util.TextureManager;
import edu.ieslaferreria.creditsintesis.logicgame.Parameter;

/**
 * Started Date: Aug 19, 2004<br><br>
 *
 * This program introduces jME's terrain utility classes and how they are used.  It
 * goes over ProceduralTextureGenerator, ImageBasedHeightMap, MidPointHeightMap, and
 * TerrainBlock.
 * 
 * @author Josep Cañellas
 */
public class CaveMazeTerrain implements TerrainManager {
    private static final float X = 10;
    private static final float O = 1;
    private static final float Y = 1.3f;
    String name;
    ConfigurationMapEvent event;

    int totalSizeMap = 129;
    float[]  map = new float[this.totalSizeMap*totalSizeMap];

    public TerrainPage buildTerrain(Node rootNode) {
        return this.buildTerrain(rootNode,"defaultTerrain",17,this.totalSizeMap,new Vector3f(10f, 10f, 10f),"PlaneTerrain");
    }

    public Sky buildSky(Node rootNode, TerrainPage terrain) {
        Sky dome = new Sky();
        rootNode.attachChild(dome);
        return dome;
    }

    public LightState buildLighting() {
            /** Set up a basic, default light. */
        DirectionalLight light = new DirectionalLight();
        light.setDiffuse(new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f));
        light.setAmbient(new ColorRGBA(0.5f, 0.5f, 0.5f, 1.0f));
        light.setDirection(new Vector3f(1,-1,0));
        light.setEnabled(true);

          /** Attach the light to a lightState and the lightState to rootNode. */
        LightState lightState = DisplaySystem.getDisplaySystem().getRenderer()
                                                              .createLightState();
        lightState.setEnabled(true);
        lightState.attach(light);
        return lightState;
    }

    public TerrainPage buildTerrain(Node rootNode, String name, int blocksize, int size, Vector3f vector3f, String modelName) {
        this.totalSizeMap=size;
        this.event= new ConfigurationMapEvent(modelName);

        TerrainPage res;
        PiecesOfMap contructorMaps = new PiecesOfMap();
        CullState cs = DisplaySystem.getDisplaySystem().getRenderer().createCullState();
        cs.setCullFace(CullState.Face.Back);
        cs.setEnabled(true);
        rootNode.setRenderState(cs);
    // This will be the texture for the terrain.

int fil=0;
int col=0;
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.PLAIN_0,PiecesOfMap.G_0,fil,col++,this.totalSizeMap);
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.PLAIN_0,PiecesOfMap.G_0,fil,col++,this.totalSizeMap);
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.PLAIN_0,PiecesOfMap.G_0,fil,col++,this.totalSizeMap);
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.PLAIN_0,PiecesOfMap.G_0,fil,col++,this.totalSizeMap);
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.PLAIN_0,PiecesOfMap.G_0,fil,col++,this.totalSizeMap);
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.PLAIN_0,PiecesOfMap.G_0,fil,col++,this.totalSizeMap);
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.PLAIN_0,PiecesOfMap.G_0,fil,col++,this.totalSizeMap);
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.PLAIN_0,PiecesOfMap.G_0,fil,col++,this.totalSizeMap);

fil++;
col=0;
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.PLAIN_0,PiecesOfMap.G_0,fil,col++,this.totalSizeMap);
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.PLAIN_0,PiecesOfMap.G_0,fil,col++,this.totalSizeMap);
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.CURVE_RIGHT,PiecesOfMap.G_0,fil,col++,this.totalSizeMap);
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.T_CHUNK,PiecesOfMap.G_0,fil,col++,this.totalSizeMap);
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.STRAIGHT_LINE,PiecesOfMap.G_90,fil,col++,this.totalSizeMap);
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.STRAIGHT_LINE,PiecesOfMap.G_90,fil,col++,this.totalSizeMap);
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.CURVE_RIGHT,PiecesOfMap.G_180,fil,col++,this.totalSizeMap);
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.PLAIN_0,PiecesOfMap.G_0,fil,col++,this.totalSizeMap);

fil++;
col=0;
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.PLAIN_0,PiecesOfMap.G_0,fil,col++,this.totalSizeMap);
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.PLAIN_0,PiecesOfMap.G_0,fil,col++,this.totalSizeMap);
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.STRAIGHT_LINE,PiecesOfMap.G_0,fil,col++,this.totalSizeMap);
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.CURVE_RIGHT,PiecesOfMap.G_270,fil,col++,this.totalSizeMap);
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.T_CHUNK,PiecesOfMap.G_0,fil,col++,this.totalSizeMap);
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.STRAIGHT_LINE,PiecesOfMap.G_90,fil,col++,this.totalSizeMap);
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.CURVE_RIGHT,PiecesOfMap.G_90,fil,col++,this.totalSizeMap);
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.PLAIN_0,PiecesOfMap.G_0,fil,col++,this.totalSizeMap);

fil++;
col=0;
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.PLAIN_0,PiecesOfMap.G_0,fil,col++,this.totalSizeMap);
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.PLAIN_0,PiecesOfMap.G_0,fil,col++,this.totalSizeMap);
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.CURVE_RIGHT,PiecesOfMap.G_270,fil,col++,this.totalSizeMap);
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.T_CHUNK,PiecesOfMap.G_0,fil,col++,this.totalSizeMap);
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.CROSS_FOUR_WAYS,PiecesOfMap.G_0,fil,col++,this.totalSizeMap);
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.STRAIGHT_LINE,PiecesOfMap.G_90,fil,col++,this.totalSizeMap);
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.SQUARE_FOUR_WAYS,PiecesOfMap.G_0,fil,col++,this.totalSizeMap);
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.PLAIN_0,PiecesOfMap.G_0,fil,col++,this.totalSizeMap);

fil++;
col=0;
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.PLAIN_0,PiecesOfMap.G_0,fil,col++,this.totalSizeMap);
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.PLAIN_0,PiecesOfMap.G_0,fil,col++,this.totalSizeMap);
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.CURVE_RIGHT,PiecesOfMap.G_0,fil,col++,this.totalSizeMap);
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.CURVE_RIGHT,PiecesOfMap.G_180,fil,col++,this.totalSizeMap);
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.CURVE_RIGHT,PiecesOfMap.G_270,fil,col++,this.totalSizeMap);
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.STRAIGHT_LINE,PiecesOfMap.G_90,fil,col++,this.totalSizeMap);
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.SQUARE_FOUR_WAYS,PiecesOfMap.G_0,fil,col++,this.totalSizeMap);
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.PLAIN_0,PiecesOfMap.G_0,fil,col++,this.totalSizeMap);

fil++;
col=0;
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.PLAIN_0,PiecesOfMap.G_0,fil,col++,this.totalSizeMap);
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.PLAIN_0,PiecesOfMap.G_0,fil,col++,this.totalSizeMap);
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.CURVE_RIGHT,PiecesOfMap.G_270,fil,col++,this.totalSizeMap);
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.STRAIGHT_LINE,PiecesOfMap.G_90,fil,col++,this.totalSizeMap);
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.STRAIGHT_LINE,PiecesOfMap.G_90,fil,col++,this.totalSizeMap);
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.STRAIGHT_LINE,PiecesOfMap.G_90,fil,col++,this.totalSizeMap);
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.SQUARE_FOUR_WAYS,PiecesOfMap.G_180,fil,col++,this.totalSizeMap);
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.PLAIN_0,PiecesOfMap.G_0,fil,col++,this.totalSizeMap);

fil++;
col=0;
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.PLAIN_0,PiecesOfMap.G_0,fil,col++,this.totalSizeMap);
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.PLAIN_0,PiecesOfMap.G_0,fil,col++,this.totalSizeMap);
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.PLAIN_0,PiecesOfMap.G_0,fil,col++,this.totalSizeMap);
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.PLAIN_0,PiecesOfMap.G_0,fil,col++,this.totalSizeMap);
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.PLAIN_0,PiecesOfMap.G_0,fil,col++,this.totalSizeMap);
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.PLAIN_0,PiecesOfMap.G_0,fil,col++,this.totalSizeMap);
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.PLAIN_0,PiecesOfMap.G_0,fil,col++,this.totalSizeMap);
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.PLAIN_0,PiecesOfMap.G_0,fil,col++,this.totalSizeMap);

fil++;
col=0;
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.PLAIN_0,PiecesOfMap.G_0,fil,col++,this.totalSizeMap);
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.PLAIN_0,PiecesOfMap.G_0,fil,col++,this.totalSizeMap);
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.PLAIN_0,PiecesOfMap.G_0,fil,col++,this.totalSizeMap);
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.PLAIN_0,PiecesOfMap.G_0,fil,col++,this.totalSizeMap);
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.PLAIN_0,PiecesOfMap.G_0,fil,col++,this.totalSizeMap);
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.PLAIN_0,PiecesOfMap.G_0,fil,col++,this.totalSizeMap);
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.PLAIN_0,PiecesOfMap.G_0,fil,col++,this.totalSizeMap);
contructorMaps.addNewPieceOnMap(this.map,PiecesOfMap.PLAIN_0,PiecesOfMap.G_0,fil,col++,this.totalSizeMap);

         res = new TerrainPage(name, blocksize, this.totalSizeMap, vector3f,this.map );

 // Add the texture
        this.setTexture(res);
        rootNode.attachChild(res);
        this.getEvent().addParameter("Blocksize",new Parameter(blocksize));
        this.getEvent().addParameter("Size",new Parameter(size));
        this.getEvent().addParameter("Vector3f",new Parameter(vector3f));
        this.getEvent().addParameter("Map",new Parameter(this.map));

        return res;
    }

    public ConfigurationMapEvent getEvent() {
        return this.event;
    }

    public TerrainPage buildRemoteTerrain(Node rootNode, String name, int blocksize, int size, Vector3f vector3f, float[] map, String modelTerrainName) {
        TerrainPage res = new TerrainPage(name, blocksize, this.totalSizeMap, vector3f,map );
        this.setTexture(res);
        // Attach the terrain TriMesh to our rootNode
        rootNode.attachChild(res);
        return res;

    }

    private void setTexture(TerrainPage terrain){
        TextureState ts = DisplaySystem.getDisplaySystem().getRenderer().createTextureState();
        URL grass=CaveMazeTerrain.class.getClassLoader().getResource(
            "texture/grassb.png");
        ts.setTexture(TextureManager.loadTexture(grass,
                Texture.MinificationFilter.BilinearNearestMipMap,
                Texture.MagnificationFilter.Bilinear));
        terrain.setRenderState(ts);


        // Give the terrain a bounding box.
        terrain.setModelBound(new BoundingBox());
        terrain.updateModelBound();

        // Attach the terrain TriMesh to our rootNode


    }
}